package com.caird.pmp.iot;

import com.caird.pmp.iot.server.BbChannelManager;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.PreDestroy;

@Slf4j
@Configuration
public class Server implements ApplicationRunner {

    @Autowired
    RedisTemplate redisTemplate;

    @Value("${app.server.port}")
    private int port;

    @Autowired
    private BbChannelManager bbChannelManager;

    private EventLoopGroup bossGroup = new NioEventLoopGroup();
    private EventLoopGroup workerGroup = new NioEventLoopGroup();

    @Override
    public void run(ApplicationArguments args) {

        redisTemplate.delete("pmp-onlines");

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(bbChannelManager)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true);

        ChannelFuture channelFuture = null;
        try {
            channelFuture = bootstrap.bind(port).sync();
        } catch (Exception e){
            log.info("Server(port={})启动异常", port);
            e.printStackTrace();
        } finally {
            if (channelFuture.isSuccess()) {
                log.info("Server(port={})启动成功", port);
            } else {
                log.info("Server(port={})启动失败", port);
            }
        }
    }

    @PreDestroy
    public void destroy() {
        bossGroup.shutdownGracefully().syncUninterruptibly();
        workerGroup.shutdownGracefully().syncUninterruptibly();
        log.info("Server(port={})关闭", port);
    }
}
